(function( $ ){
	
var tree = {
    init : function( options ) {
		var settings = $.extend({
			items: [],
			onclick: function(item) { return true; },
			ontoggle: function(item) {},
			expand: false,
			checkboxes : false
		}, options);
		this.addClass('tree');
		tree.addTreeItems(this, settings.items, settings.ontoggle, settings.onclick, settings.checkboxes);
		tree.expand.apply(this,[settings.expand]);
	},
	expand : function(items) {
		switch (items) {
			case 'all': this.find('li').addClass('o'); break;
			case 'top': this.children('ul').children('li').addClass('o'); break;
		}
	},
	checked : function(ids) {
		if (ids) {
			var ctrl = this;
			$.each(ids,function(i,id){
				ctrl.find('li[data-id='+id+']').children('span').find('input:first-child').prop('checked',true);
			})
		} else {
			var ids = [];
			$.each(this.find('input:first-child:checked'),function(i,input){
				ids.push($(input).closest('li').attr('data-id'));
			});
			return ids;
		}
		return this;
	},
	addTreeItems : function (parent,items,ontoggle,onclick,checkboxes) {
		if (items.length) {
			var ul = $('<ul>');
			$.each(items,function(i,item){
				var li = $('<li>')
					.attr('data-id',item.id)
					.attr('data-name',item.name)
					.addClass(item.children.length ? '' : 'l')
					.append( 
						$('<span>')
							.click(function(){ 
								$(this).closest('li').toggleClass('o'); 
								ontoggle($(this).closest('li'));
							})
							.append(
								$('<a>')
									.attr('href',item.url?item.url:'#')
									.html(item.name)
									.click(function(e,checked){
										if (checkboxes && !checked) {
											var input = $(this).closest('span').find('input');
											input.prop('checked',!input.prop('checked'));
										}
										e.stopPropagation();
										return onclick($(this).closest('li'));
									})
							) 
					);
				if (checkboxes) {
					li.find('a').before($('<input>').attr('type','checkbox').click(function(e){ 
						e.stopPropagation();
						$(this).closest('span').children('a').trigger('click',true);
					}));
				}
				ul.append(li);
				tree.addTreeItems(li,item.children,ontoggle,onclick,checkboxes);
			});
			parent.append(ul);
		}
	}
};
	
$.fn.tree = function( method ) {
	if (tree[method]) {
		return tree[ method ].apply( this, Array.prototype.slice.call( arguments, 1 ));
	} else if ( typeof method === 'object' || ! method ) {
		return tree.init.apply( this, arguments );
	} else {
		$.error( 'Method ' +  method + ' does not exist on jQuery.tree' );
	}
};
	
})( jQuery );